/**
 * @file basic_example.cpp
 * @brief KWDB SDK基础使用示例 - 基于gRPC的高性能SDK
 */

#include "kwdb_sdk.h"
#include <iostream>
#include <vector>
#include <chrono>
#include <thread>

using namespace kwdb;

/**
 * @brief 基础示例主函数
 */
int main() {
    std::cout << "=== KWDB C++ SDK 基础示例 ===" << std::endl;
    
    try {
        // 创建客户端配置
        ClientConfig config("localhost", 9090);
        config.setBatchSize(1000)
              .setBatchTimeout(100)
              .setThreadPoolSize(10)
              .setEnableCompression(true)
              .setKeepAlive(true);
        
        // 创建客户端
        KWDBClient client(config);
        
        // 连接服务器
        std::cout << "正在连接KWDB服务器..." << std::endl;
        client.connect();
        std::cout << "连接成功！" << std::endl;
        
        // 示例1: 写入单条数据
        std::cout << "\n=== 示例1: 写入单条数据 ===" << std::endl;
        writeSingleDataPoint(client);
        
        // 示例2: 批量写入数据
        std::cout << "\n=== 示例2: 批量写入数据 ===" << std::endl;
        writeBatchData(client);
        
        // 示例3: 异步写入数据
        std::cout << "\n=== 示例3: 异步写入数据 ===" << std::endl;
        writeDataAsync(client);
        
        // 示例4: 流式写入数据
        std::cout << "\n=== 示例4: 流式写入数据 ===" << std::endl;
        writeDataStream(client);
        
        // 示例5: 查询数据
        std::cout << "\n=== 示例5: 查询数据 ===" << std::endl;
        queryData(client);
        
        // 示例6: 使用查询构建器
        std::cout << "\n=== 示例6: 使用查询构建器 ===" << std::endl;
        queryWithBuilder(client);
        
        // 示例7: 流式查询
        std::cout << "\n=== 示例7: 流式查询 ===" << std::endl;
        queryStreamData(client);
        
        // 示例8: Line Protocol解析
        std::cout << "\n=== 示例8: Line Protocol解析 ===" << std::endl;
        parseLineProtocol(client);
        
        // 等待异步操作完成
        std::this_thread::sleep_for(std::chrono::seconds(2));
        
        // 断开连接
        client.disconnect();
        std::cout << "\n连接已断开" << std::endl;
        
    } catch (const std::exception& e) {
        std::cerr << "操作失败: " << e.what() << std::endl;
        return 1;
    }
    
    return 0;
}

/**
 * @brief 写入单条数据示例
 */
void writeSingleDataPoint(KWDBClient& client) {
    try {
        // 创建数据点
        DataPoint dataPoint("temperature");
        dataPoint.addTag("location", "beijing")
                 .addTag("device", "sensor001")
                 .addField("value", 25.5)
                 .addField("humidity", 60)
                 .addField("status", "normal");
        
        // 写入数据
        client.write(dataPoint);
        std::cout << "单条数据写入成功: " << dataPoint.toLineProtocol() << std::endl;
        
    } catch (const std::exception& e) {
        std::cerr << "单条写入失败: " << e.what() << std::endl;
    }
}

/**
 * @brief 批量写入数据示例
 */
void writeBatchData(KWDBClient& client) {
    try {
        std::vector<DataPoint> dataPoints;
        
        // 创建多个数据点
        for (int i = 0; i < 5; i++) {
            DataPoint dataPoint("pressure");
            dataPoint.addTag("location", "shanghai")
                     .addTag("device", "sensor" + std::to_string(i))
                     .addField("value", 1013.25 + i)
                     .addField("unit", "hPa")
                     .setTimestamp(std::chrono::duration_cast<std::chrono::milliseconds>(
                         std::chrono::system_clock::now().time_since_epoch()).count() - (5 - i) * 1000);
            
            dataPoints.push_back(dataPoint);
        }
        
        // 批量写入
        client.writeBatch(dataPoints);
        std::cout << "批量数据写入成功，共 " << dataPoints.size() << " 条记录" << std::endl;
        
    } catch (const std::exception& e) {
        std::cerr << "批量写入失败: " << e.what() << std::endl;
    }
}

/**
 * @brief 异步写入数据示例
 */
void writeDataAsync(KWDBClient& client) {
    try {
        // 创建数据点
        DataPoint dataPoint("wind_speed");
        dataPoint.addTag("location", "guangzhou")
                 .addTag("device", "weather_station")
                 .addField("speed", 15.2)
                 .addField("direction", "NE")
                 .addField("unit", "m/s");
        
        // 异步写入
        auto future = client.writeAsync(dataPoint);
        future.wait();
        
        std::cout << "异步数据写入成功: " << dataPoint.toLineProtocol() << std::endl;
        
    } catch (const std::exception& e) {
        std::cerr << "异步写入失败: " << e.what() << std::endl;
    }
}

/**
 * @brief 流式写入数据示例
 */
void writeDataStream(KWDBClient& client) {
    try {
        std::vector<DataPoint> dataPoints;
        
        // 创建大量数据点
        for (int i = 0; i < 100; i++) {
            DataPoint dataPoint("sensor_data");
            dataPoint.addTag("location", "factory")
                     .addTag("device", "sensor" + std::to_string(i))
                     .addField("value", static_cast<double>(rand()) / RAND_MAX * 100)
                     .addField("timestamp", std::chrono::duration_cast<std::chrono::milliseconds>(
                         std::chrono::system_clock::now().time_since_epoch()).count() - i * 1000);
            
            dataPoints.push_back(dataPoint);
        }
        
        // 流式写入
        auto future = client.writeStreamAsync(dataPoints);
        future.wait();
        
        std::cout << "流式数据写入成功，共 " << dataPoints.size() << " 条记录" << std::endl;
        
    } catch (const std::exception& e) {
        std::cerr << "流式写入失败: " << e.what() << std::endl;
    }
}

/**
 * @brief 查询数据示例
 */
void queryData(KWDBClient& client) {
    try {
        // 执行SQL查询
        std::string sql = "SELECT * FROM temperature WHERE location = 'beijing' LIMIT 10";
        QueryResult result = client.query(sql);
        
        std::cout << "查询结果:" << std::endl;
        std::cout << "列数: " << result.getColumns().size() << std::endl;
        std::cout << "行数: " << result.getRows().size() << std::endl;
        std::cout << "执行时间: " << result.getExecutionTime() << "ms" << std::endl;
        
        // 遍历结果
        for (const auto& row : result.getRows()) {
            std::cout << "行数据: " << row->toString() << std::endl;
        }
        
    } catch (const std::exception& e) {
        std::cerr << "查询失败: " << e.what() << std::endl;
    }
}

/**
 * @brief 使用查询构建器示例
 */
void queryWithBuilder(KWDBClient& client) {
    try {
        // 使用查询构建器
        QueryResult result = client.queryBuilder()
            .select("location", "device", "value")
            .from("pressure")
            .where("location = 'shanghai'")
            .orderBy("timestamp", "DESC")
            .limit(5)
            .execute();
        
        std::cout << "查询构建器结果:" << std::endl;
        std::cout << "行数: " << result.getRows().size() << std::endl;
        
        // 遍历结果
        for (const auto& row : result.getRows()) {
            std::string location = row->getValue("location");
            std::string device = row->getValue("device");
            std::string value = row->getValue("value");
            std::cout << "位置: " << location << ", 设备: " << device << ", 值: " << value << std::endl;
        }
        
    } catch (const std::exception& e) {
        std::cerr << "查询构建器失败: " << e.what() << std::endl;
    }
}

/**
 * @brief 流式查询示例
 */
void queryStreamData(KWDBClient& client) {
    try {
        std::string sql = "SELECT * FROM sensor_data WHERE location = 'factory' LIMIT 1000";
        
        auto future = client.queryStreamAsync(sql);
        QueryResult result = future.get();
        
        std::cout << "流式查询结果:" << std::endl;
        std::cout << "行数: " << result.getRows().size() << std::endl;
        std::cout << "执行时间: " << result.getExecutionTime() << "ms" << std::endl;
        
    } catch (const std::exception& e) {
        std::cerr << "流式查询失败: " << e.what() << std::endl;
    }
}

/**
 * @brief Line Protocol解析示例
 */
void parseLineProtocol(KWDBClient& client) {
    try {
        // 解析Line Protocol格式数据
        std::string lineProtocol = "cpu,host=server01,region=us-west usage=0.64,idle=0.36 1434055562000000000";
        
        DataPoint dataPoint = client.parseLineProtocol(lineProtocol);
        std::cout << "解析成功:" << std::endl;
        std::cout << "测量: " << dataPoint.getMeasurement() << std::endl;
        std::cout << "标签: ";
        for (const auto& [key, value] : dataPoint.getTags()) {
            std::cout << key << "=" << value << " ";
        }
        std::cout << std::endl;
        std::cout << "字段: ";
        for (const auto& [key, value] : dataPoint.getFields()) {
            std::cout << key << "=" << value << " ";
        }
        std::cout << std::endl;
        std::cout << "时间戳: " << dataPoint.getTimestamp() << std::endl;
        
        // 转换回Line Protocol格式
        std::string converted = client.toLineProtocol(dataPoint);
        std::cout << "转换回Line Protocol: " << converted << std::endl;
        
    } catch (const std::exception& e) {
        std::cerr << "Line Protocol解析失败: " << e.what() << std::endl;
    }
}
